const webpack = require('webpack')
const path = require('path')

const envAll = require('./env.js')
const chunkAll = require('./chunk.js')
const envInfo = envAll.environment[process.env.APP_ENV]
const chunkInfo = chunkAll[process.env.APP_ENV]
const vueConfBase = require('./config/vueConfBase')
const settings = require('./src/settings')
// const HardSourceWebpackPlugin = require("hard-source-webpack-plugin");
const colors = require('colors-console')
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin')

const pages = {
  index: {
    // entry for the page
    entry: 'src/main.js',
    title: settings.siteTitle
  }
}

let currentPort = '' // 端口号

// npm run serve -- --chunk、 npm run serve:test -- --chunk
// if (process.argv.indexOf('--chunk') > -1) {

// 是否需要启动chunk服务
// npm run serve --chunk
if (process.env.npm_config_chunk) {
  pages['chunkPage'] = {
    entry: './chunk/mainChunk.js'
  }
}

// 判断是 serve 还是 build
let scriptType = ''
if (process.env.npm_lifecycle_event.indexOf('serve') > -1) {
  scriptType = 'serve'
} else if (process.env.npm_lifecycle_event.indexOf('build') > -1) {
  scriptType = 'build'
  // 以生产的模式打包以保证测试生产效果一致
  process.env.NODE_ENV = 'production'
}

module.exports = {
  pages,
  // 项目上下文
  publicPath: scriptType === 'serve' ? '' : envAll.publicPath,
  // eslint-loader 是否在保存的时候检查,
  lintOnSave: false,
  // 打包输出的文件夹
  outputDir: `dist/${envInfo.env}`,
  // 非生产显示source-map
  productionSourceMap: scriptType === 'build' && envInfo.env !== 'prod',
  devServer: {
    // host: '0.0.0.0',
    port: settings.port || '8080',
    onListening: function (devServer) {
      currentPort = devServer.listeningApp.address().port
    }
    // 方便chunk本地调试，本地chunk打包后，chunk.js 中配置配置 "./chunk/hello/index.js" 会从 dist/chunk/hello/index.js 找资源
    // contentBase: [path.join(__dirname, 'dist'), path.join(__dirname, 'public')],
    // headers: {
    //   "Access-Control-Allow-Origin": "*",
    //   "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
    //   "Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
    // }
  },
  // https://cli.vuejs.org/zh/guide/webpack.html#%E7%AE%80%E5%8D%95%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%B9%E5%BC%8F
  // 自定义 webpack 配置
  configureWebpack: (config) => {
    // 设置一些别名
    const alias = {
      src: path.join(__dirname, 'src'),
      chunk: path.join(__dirname, 'chunk')
    }
    config.resolve.alias = { ...config.resolve.alias, ...alias }

    config.plugins.push(
      new webpack.DefinePlugin({
        SCRIPT_TYPE: JSON.stringify(scriptType) // serve为开发模式， build为打包模式
      })
    )

    // 用到 monacto-editor 的时候需要打开以自动引入woerk等
    // config.plugins.push(
    //   new MonacoWebpackPlugin({
    //     features: ['!gotoSymbol'],
    //     languages: ['javascript', 'css', 'html', 'typescript', 'json']
    //   })
    // )

    // 打包的环境[npm run build:xxx] EPENV、EPCHUNK 通过 DefinePlugin 设置全局变量
    // 开发的模式[npm run serve:xxx] 通过下面的方法生成本地js window.EPENV window.EPCHUNK注册
    if (scriptType === 'serve') {
      // DefinePlugin.runtimeValue webpack 5 可以 runtime 貌似
      config.plugins.push(
        new webpack.DefinePlugin({
          EPENV: JSON.stringify(envInfo),
          EPCHUNK: JSON.stringify(chunkInfo)
        })
      )
      config.plugins.push({
        apply: (compiler) => {
          compiler.hooks.done.tap('done', () => {
            console.log(`${colors('blue', '当前环境')}：${process.env.APP_ENV}`)
            console.log(
              `${colors('blue', 'chunk服务')}：${
                process.env.npm_config_chunk
                  ? `http://localhost:${currentPort}/chunkPage.html`
                  : '未启动'
              }`
            )
            console.log(
              `${colors(
                'blue',
                '开发文档'
              )}： http://192.168.0.40/confluence/pages/viewpage.action?pageId=61576962`
            )
            console.log(
              `-----------------------------------------------------------------------------`
            )
          })
        }
      })
    }

    /**
     * 打包完成的回调方法
     */
    if (scriptType === 'build') {
      config.plugins.push({
        apply: (compiler) => {
          compiler.hooks.done.tap('done', () => {
            // 打包 env chunk 的配置文件
            vueConfBase.createStaticEnvFile(`dist/${envInfo.env}`, envInfo)
            vueConfBase.createStaticChunkFile(`dist/${envInfo.env}`, chunkInfo)
            // #EPFC-epin-start
            // 打包 epin
            if (settings.epin) {
              require('./bin/build-epin.js')
            }
            // #EPFC-epin-end
          })
        }
      })
    }

    // config.externals = {
    //   '@easipass/epin-render-plus': {
    //     commonjs: '@easipass/epin-render-plus/dist/epinRenderPlus.min.simple.js',
    //     commonjs2: '@easipass/epin-render-plus/dist/epinRenderPlus.min.simple.js',
    //     amd: '@easipass/epin-render-plus/dist/epinRenderPlus.min.simple.js',
    //     root: 'epinRenderPlus',
    //   }
    // }

    config.plugins
      .push
      // new HardSourceWebpackPlugin({
      //   // cacheDirectory: './../../../node_build_cache/[confighash]',
      //   // cachePrune: {
      //   //   // 缓存的存在时间，默认为两天
      //   //   maxAge: 2 * 24 * 60 * 60 * 1000,
      //   //   // 缓存的最大容量，默认为 50 MB
      //   //   sizeThreshold: 50 * 1024 * 1024,
      //   // },
      // }),
      // new HardSourceWebpackPlugin.ExcludeModulePlugin([
      //   {
      //     // HardSource works with mini-css-extract-plugin but due to how
      //     // mini-css emits assets, assets are not emitted on repeated builds with
      //     // mini-css and hard-source together. Ignoring the mini-css loader
      //     // modules, but not the other css loader modules, excludes the modules
      //     // that mini-css needs rebuilt to output assets every time.
      //     test: /mini-css-extract-plugin[\\/]dist[\\/]loader/
      //   }
      // ]),
      // 节约编译的时间，告诉 webpack 公共库文件已经编译好了，减少 webpack 对公共库的编译时间 详见 webpack.dll.config
      // https://juejin.cn/post/6844903790638792711
      // new webpack.DllReferencePlugin({
      //   context:  process.cwd(),
      //   manifest: require('./public/vendor/vue-manifest.json')
      // }),
      // new webpack.DllReferencePlugin({
      //   context: process.cwd(),
      //   manifest: require('./public/vendor/lib-manifest.json')
      // }),
      // #EPFC-epin-start
      // new webpack.DllReferencePlugin({
      //   context: process.cwd(),
      //   manifest: require('./public/vendor/plugin-manifest.json')
      // })
      // #EPFC-epin-end
      ()
  },
  // transpileDependencies: ['asn1.js', 'asn1'],
  chainWebpack: (config) => {
    // 指定编译一些库
    config.module
      .rule('transform-uncompile-js')
      .test(/\.js$/)
      .include.add(/node_modules[\\\/]@easipass[\\\/].*/)
      .add(/node_modules[\\\/]asn1|node_modules[\\\/]asn1.js/)
      // .add(/node_modules[\\\/]@easipass[\\\/]utils/)
      // .add(/node_modules[\\\/]@easipass[\\\/]basic/)
      // .add(/node_modules[\\\/]@easipass[\\\/]epin/)
      // .add(/node_modules[\\\/]@easipass[\\\/]area-data/)
      // .add(/node_modules[\\\/]@easipass[\\\/]chunk-render/)
      .add(/node_modules[\\\/]wujie/)
      // .add(/node_modules[\\\/]@easipass[\\\/]epin-render-plus/)
      .end()
      .exclude.add(/node_modules[\\\/]@easipass[\\\/]epin-render-plus[\\\/]dist/)
      .end()
      .use('babel')
      .loader('babel-loader')

    // svg相关处理
    config.module
      // 默认的svg处理排除这个目录
      .rule('svg')
      .exclude.add(path.resolve('src/components/svg-cpt'))
      .end()

    config.module
      // 这个目录svg特殊处理
      .rule('svg-cpt')
      .test(/\.svg$/)
      .include.add(path.resolve('src/components/svg-cpt'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'epsvgcpt-[name]'
      })
      .end()
    // elliptic 会将打包的路径信息打包进去
    config.module
      .rule('remove-path-info')
      .test(/package\.json$/)
      .use('package-json-cleanup-loader')
      .loader('package-json-cleanup-loader')
      .options({
        only: ['name', 'version']
      })
      .end()
  }
}
